### -*- coding: utf-8 -*- #############################################
# Разработано компанией Ключевые Решения (http://keysolutions.ru/)
# Все права защищены, 2006-2007
#
# Developed by Key Solutions (http://keysolutions.ru/)
# All right reserved, 2006-2007
#######################################################################
"""DataAdd classes for the Zope 3 based diplom.browser package

$Id: geneticview.py 65 2007-12-28 20:27:50Z Arvi3D $
"""
__author__  = "Arvid"
__license__ = "ZPL"
__version__ = "$Revision: 65 $"
__date__ = "$Date: 2007-12-28 22:27:50 +0200 (Fri, 28 Dec 2007) $"

from zope.interface import Interface
from zope.app.i18n import ZopeMessageFactory as _
from zope.formlib.form import AddForm, EditForm, applyChanges, Fields, Field, haveInputWidgets, action
from zope.formlib.namedtemplate import NamedTemplate, NamedTemplateImplementation
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app import zapi
from zope.schema import getFieldsInOrder
from zope.schema.fieldproperty import FieldProperty
from zope.app.container.interfaces import IAdding

from diplom.interfaces import IDistributingFactory, IGenetic
from interfaces import IGeneration, IExploringForm
from diplom.data import Data

from random import random

class DataAddByGenerationExpoExpo(AddForm) :

    label= _(u"Generate on two exponential distributing")

    firstDistr = 'exponential'
    secondDistr = 'exponential'

    @property
    def firstFactory(self):
        return zapi.getUtility(IDistributingFactory, name = self.firstDistr, context = self.context)

    @property
    def secondFactory(self):
        return zapi.getUtility(IDistributingFactory, name = self.secondDistr, context = self.context)

    @property
    def form_fields(self):
        return Fields(IGeneration, *tuple([Fields(*tuple([Field(field, prefix = str(i))
                                                          for n, field in getFieldsInOrder(factory.params)
                                                          ])) \
                            for i, factory in enumerate([self.firstFactory, self.secondFactory])
                            ]))

    def create(self, data):
        return self.generate(data)

    def generate(self, data):
        dimension = data.pop('dimension')
        weight = data.pop('weight')

        firstFactory = self.firstFactory
        secondFactory = self.secondFactory

        params = [[],[]]
        for n, p in data.items():
            params[int(n[0])].append( (n[2:],p) )

        vector = []

        for i in range(dimension):
            if random() <= weight:
                vector.append(firstFactory.generate(**dict(params[0])))
            else:
                vector.append(secondFactory.generate(**dict(params[1])))

        vector.sort()

        data = Data(vector)

        data.firstDistr = self.firstDistr
        data.secondDistr = self.secondDistr

        data.weight = weight
        data.params = params

        IGenetic(data).runAlgorithm(data)

        return data

class ExploringAdapter(object):

    weightStep = FieldProperty(IExploringForm['weightStep'])
    minLambda = FieldProperty(IExploringForm['minLambda'])
    maxLambda = FieldProperty(IExploringForm['maxLambda'])
    lambdaStep = FieldProperty(IExploringForm['lambdaStep'])

    def __init__(self, folder):
        super(ExploringAdapter, self).__init__()

TEST_DIMENSION = 100

class ExploringAlgorithm(EditForm):
    form_fields = Fields(IExploringForm)
    label = _(u"Generate many datas for exploring algorithm")

    @action(_("Generate"), condition=haveInputWidgets)
    def handle_edit_action(self, action, data):
        EditForm.handle_edit_action.success_handler(self, action, data)
        self.createAndAdd(data)

    def createAndAdd(self, data):
        adding = zapi.getMultiAdapter((self.context, self.request),
                             #interface = IAdding,
                             name = "+"
                             )
        adapter = zapi.getMultiAdapter((adding, self.request),
                             #interface = IAdding,
                             name = "GenSelectionExpoExpo.html"
                             )

        addingForm = dict([(field.__name__, None) for field in adapter.form_fields])

        lambdaStep = data['lambdaStep']
        w = 0.0
        while(w <= 1.0):
            lambda1 = data['minLambda']
            lambda2 = data['maxLambda']

            while(lambda1 <= data['maxLambda'] and lambda2 >= data['minLambda']):
                addingForm['dimension'] = TEST_DIMENSION
                addingForm['weight'] = w

                addingForm['0.lambd'] = lambda1
                addingForm['1.lambd'] = lambda2

                print addingForm
                #Это необходимо для самостоятельного выбора имени
                adapter.context.contentName = ''
                adapter.createAndAdd(addingForm)

                lambda1 += lambdaStep
                lambda2 -= lambdaStep

            w += data['weightStep']


form_template = NamedTemplateImplementation( ViewPageTemplateFile('generation.pt') )